/**
 * Bilibili下载器 - 内容脚本
 * 
 * 负责处理以下功能：
 * 1. 从Bilibili网页提取视频信息
 * 2. 解析视频播放地址
 * 3. 向扩展发送视频数据
 */

// 初始化
(function() {
  console.log('Bilibili下载器 - 内容脚本已加载');
  
  // 初始化界面元素
  initializeUI();
  
  // 监听网页URL变化
  watchPageChanges();
  
  // 监听来自扩展的消息
  chrome.runtime.onMessage.addListener(handleMessages);
})();

/**
 * 初始化下载器UI
 */
function initializeUI() {
  // 添加下载按钮到视频播放页面
  if (isVideoPage()) {
    setTimeout(() => {
      addDownloadButton();
    }, 1500); // 延迟添加按钮，确保页面元素加载完成
  }
}

/**
 * 监听网页变化
 */
function watchPageChanges() {
  // 使用MutationObserver检测DOM变化
  const observer = new MutationObserver(mutations => {
    if (isVideoPage() && !document.querySelector('.bilibili-downloader-btn')) {
      addDownloadButton();
    }
  });
  
  // 开始观察
  observer.observe(document.body, {
    childList: true,
    subtree: true
  });
  
  // 监听URL变化
  let lastUrl = location.href;
  new MutationObserver(() => {
    const url = location.href;
    if (url !== lastUrl) {
      lastUrl = url;
      if (isVideoPage()) {
        setTimeout(() => {
          addDownloadButton();
        }, 1500);
      }
    }
  }).observe(document, { subtree: true, childList: true });
}

/**
 * 处理来自扩展的消息
 * @param {Object} message - 消息对象
 * @param {Object} sender - 发送者信息
 * @param {Function} sendResponse - 回复函数
 */
function handleMessages(message, sender, sendResponse) {
  if (message.action === 'getVideoInfo') {
    extractVideoInfo()
      .then(videoInfo => {
        sendResponse({ success: true, videoInfo: videoInfo });
      })
      .catch(error => {
        console.error('获取视频信息失败:', error);
        sendResponse({ success: false, error: error.message });
      });
    return true; // 异步响应
  }
}

/**
 * 判断当前页面是否为视频播放页面
 * @returns {boolean} 是否为视频页面
 */
function isVideoPage() {
  return location.href.includes('bilibili.com/video/');
}

/**
 * 添加下载按钮到视频播放页面
 */
function addDownloadButton() {
  // 如果按钮已存在，则不再添加
  if (document.querySelector('.bilibili-downloader-btn')) {
    return;
  }
  
  // 查找视频控制栏
  const controlBar = document.querySelector('.bpx-player-control-bottom-right') || 
                    document.querySelector('.bilibili-player-video-control-bottom-right');
  
  if (!controlBar) {
    console.warn('未找到视频控制栏，无法添加下载按钮');
    return;
  }
  
  // 创建下载按钮
  const downloadBtn = document.createElement('div');
  downloadBtn.className = 'bilibili-downloader-btn';
  downloadBtn.title = '使用Bilibili下载器下载视频';
  downloadBtn.innerHTML = `
    <svg viewBox="0 0 24 24" width="22" height="22">
      <path fill="currentColor" d="M19,9h-4V3H9v6H5l7,7L19,9z M5,18v2h14v-2H5z"></path>
    </svg>
  `;
  downloadBtn.style.cssText = `
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    cursor: pointer;
    color: white;
    margin-right: 8px;
    opacity: 0.9;
    transition: opacity 0.2s;
  `;
  
  // 添加悬停效果
  downloadBtn.addEventListener('mouseover', () => {
    downloadBtn.style.opacity = '1';
  });
  
  downloadBtn.addEventListener('mouseout', () => {
    downloadBtn.style.opacity = '0.9';
  });
  
  // 添加点击事件
  downloadBtn.addEventListener('click', () => {
    // 向扩展发送消息，显示下载面板
    chrome.runtime.sendMessage({ action: 'showDownloadPanel' });
    
    // 获取视频信息并发送给扩展
    extractVideoInfo()
      .then(videoInfo => {
        chrome.runtime.sendMessage({
          action: 'videoInfoExtracted',
          videoInfo: videoInfo
        });
      })
      .catch(error => {
        console.error('获取视频信息失败:', error);
        // 显示错误提示
        showToast('获取视频信息失败：' + error.message);
      });
  });
  
  // 将按钮添加到控制栏
  controlBar.insertBefore(downloadBtn, controlBar.firstChild);
}

/**
 * 提取当前视频的信息
 * @returns {Promise<Object>} 视频信息对象
 */
function extractVideoInfo() {
  return new Promise((resolve, reject) => {
    try {
      // 尝试从页面提取初始数据
      let videoInfo = {};
      
      // 1. 从页面元素获取基本信息
      videoInfo.title = getVideoTitle();
      videoInfo.cover = getVideoCover();
      videoInfo.uploader = getVideoUploader();
      videoInfo.url = window.location.href;
      videoInfo.bvid = getBvid();
      
      // 2. 尝试从页面初始状态获取更多信息
      const initialState = getInitialState();
      if (initialState) {
        // 补充额外信息
        if (initialState.videoData) {
          videoInfo.aid = initialState.videoData.aid;
          videoInfo.cid = initialState.videoData.cid;
          videoInfo.duration = initialState.videoData.duration;
        }
      }
      
      // 3. 获取视频播放地址（这部分在实际开发中需要针对Bilibili的加密方式进行特殊处理）
      // 下面示例使用了当前页面视频元素的src，这通常不是实际的视频源地址
      // 实际开发中需要通过特定的API或解析方法获取
      const videoElement = document.querySelector('video');
      if (videoElement && videoElement.src) {
        videoInfo.playUrl = videoElement.src;
      } else {
        // 模拟一个视频地址（实际开发中需要替换为真实的解析逻辑）
        // 注意：这个地址不会实际工作，仅作为演示
        videoInfo.playUrl = `https://api.bilibili.com/x/player/playurl?bvid=${videoInfo.bvid}&cid=${videoInfo.cid}`;
      }
      
      // 如果缺少关键信息，抛出错误
      if (!videoInfo.title || !videoInfo.bvid) {
        throw new Error('无法获取完整的视频信息');
      }
      
      resolve(videoInfo);
    } catch (error) {
      reject(error);
    }
  });
}

/**
 * 获取视频标题
 * @returns {string} 视频标题
 */
function getVideoTitle() {
  // 尝试多种选择器来获取标题
  const titleSelectors = [
    'h1.video-title',
    '.tit',
    '#viewbox_report h1',
    '.media-title',
    '.video-info-title',
    'h1'
  ];
  
  for (const selector of titleSelectors) {
    const element = document.querySelector(selector);
    if (element && element.textContent.trim()) {
      return element.textContent.trim();
    }
  }
  
  return '未知视频';
}

/**
 * 获取视频封面
 * @returns {string} 视频封面URL
 */
function getVideoCover() {
  // 尝试从meta标签获取封面
  const metaImage = document.querySelector('meta[property="og:image"]') || 
                   document.querySelector('meta[itemprop="image"]');
  
  if (metaImage && metaImage.content) {
    return metaImage.content;
  }
  
  // 尝试从视频播放器获取封面
  const videoCover = document.querySelector('.bpx-player-video-cover img') ||
                    document.querySelector('.bpx-player-cover-img');
  
  if (videoCover && videoCover.src) {
    return videoCover.src;
  }
  
  return '';
}

/**
 * 获取视频上传者
 * @returns {string} 上传者名称
 */
function getVideoUploader() {
  // 尝试多种选择器来获取上传者
  const uploaderSelectors = [
    '.up-name',
    '.username',
    '.author-name',
    '.up-info-name',
    'a[data-usercard-mid]'
  ];
  
  for (const selector of uploaderSelectors) {
    const element = document.querySelector(selector);
    if (element && element.textContent.trim()) {
      return element.textContent.trim();
    }
  }
  
  return '未知上传者';
}

/**
 * 获取视频BV号
 * @returns {string} BV号
 */
function getBvid() {
  // 从URL中提取BV号
  const match = location.pathname.match(/\/video\/(BV[a-zA-Z0-9]+)/);
  if (match && match[1]) {
    return match[1];
  }
  
  // 尝试从页面数据获取
  const initialState = getInitialState();
  if (initialState && initialState.videoData && initialState.videoData.bvid) {
    return initialState.videoData.bvid;
  }
  
  return '';
}

/**
 * 获取页面的初始状态数据
 * @returns {Object|null} 初始状态数据
 */
function getInitialState() {
  try {
    // 尝试从window.__INITIAL_STATE__获取
    if (window.__INITIAL_STATE__) {
      return window.__INITIAL_STATE__;
    }
    
    // 尝试从页面脚本提取
    const scripts = document.querySelectorAll('script');
    for (const script of scripts) {
      const content = script.textContent;
      if (content && content.includes('window.__INITIAL_STATE__')) {
        const match = content.match(/window\.__INITIAL_STATE__\s*=\s*(\{.+?\});/);
        if (match && match[1]) {
          return JSON.parse(match[1]);
        }
      }
    }
  } catch (error) {
    console.error('获取初始状态数据失败:', error);
  }
  
  return null;
}

/**
 * 显示提示信息
 * @param {string} message - 提示信息
 * @param {number} duration - 显示时长（毫秒）
 */
function showToast(message, duration = 3000) {
  // 检查是否已存在toast元素
  let toast = document.querySelector('.bilibili-downloader-toast');
  
  if (!toast) {
    // 创建新的toast元素
    toast = document.createElement('div');
    toast.className = 'bilibili-downloader-toast';
    toast.style.cssText = `
      position: fixed;
      top: 80px;
      left: 50%;
      transform: translateX(-50%);
      background-color: rgba(0, 0, 0, 0.7);
      color: white;
      padding: 10px 20px;
      border-radius: 4px;
      z-index: 999999;
      transition: opacity 0.3s;
      font-size: 14px;
    `;
    document.body.appendChild(toast);
  }
  
  // 设置消息内容
  toast.textContent = message;
  toast.style.opacity = '1';
  
  // 设置定时器，在指定时间后隐藏toast
  clearTimeout(toast.hideTimeout);
  toast.hideTimeout = setTimeout(() => {
    toast.style.opacity = '0';
    setTimeout(() => {
      if (toast.parentNode) {
        toast.parentNode.removeChild(toast);
      }
    }, 300);
  }, duration);
} 